﻿Imports System.ComponentModel

Namespace Controls
	''' <summary>
	''' Provides a control that allows for increasing and decreasing selections. For our purposes it uses a double for the value.
	''' </summary>
	''' <remarks></remarks>
	Public Class TimeSpanIncrementer


		''' <summary>
		''' The value of the control.
		''' </summary>
		''' <value></value>
		''' <returns></returns>
		''' <remarks></remarks>
		Public Property Value As TimeSpan
			Get
				Return GetValue(ValueProperty)
			End Get

			Set(ByVal value As TimeSpan)
				If value = GetValue(ValueProperty) Then
					Return
				End If

				CheckValue()
				If value > MaxValue Then
					value = MaxValue
				ElseIf value < MinValue Then
					value = MinValue
				End If
				SetValue(ValueProperty, value)
				If TimeHours <> value.Hours Then
					TimeHours = value.Hours
				End If
				If TimeMinutes <> value.Minutes Then
					TimeMinutes = value.Minutes
				End If
				If TimeSeconds <> value.Seconds Then
					TimeSeconds = value.Seconds
				End If
				If TimeTenths <> value.Milliseconds Then
					TimeTenths = value.Milliseconds
				End If
			End Set
		End Property

		Public Shared ReadOnly ValueProperty As DependencyProperty = _
							   DependencyProperty.Register("Value", _
							   GetType(TimeSpan), GetType(TimeSpanIncrementer), _
							   New PropertyMetadata(New TimeSpan(0)))






		''' <summary>
		''' The maximum value the control can assume.
		''' </summary>
		''' <value></value>
		''' <returns></returns>
		''' <remarks></remarks>
		Public Property MaxValue As TimeSpan
			Get
				Return GetValue(MaxValueProperty)
			End Get

			Set(ByVal value As TimeSpan)
				SetValue(MaxValueProperty, value)
				CheckValue()
			End Set
		End Property

		Public Shared ReadOnly MaxValueProperty As DependencyProperty = _
							   DependencyProperty.Register("MaxValue", _
							   GetType(TimeSpan), GetType(TimeSpanIncrementer), _
							   New PropertyMetadata(TimeSpan.MaxValue))






		''' <summary>
		''' The minimum value the control can assume.
		''' </summary>
		''' <value></value>
		''' <returns></returns>
		''' <remarks></remarks>
		Public Property MinValue As TimeSpan
			Get
				Return GetValue(MinValueProperty)
			End Get

			Set(ByVal value As TimeSpan)
				SetValue(MinValueProperty, value)
				CheckValue()
			End Set
		End Property

		Public Shared ReadOnly MinValueProperty As DependencyProperty = _
							   DependencyProperty.Register("MinValue", _
							   GetType(TimeSpan), GetType(TimeSpanIncrementer), _
							   New PropertyMetadata(New TimeSpan(0)))






		Public Property TimeHours As Integer
			Get
				Return GetValue(TimeHoursProperty)
			End Get

			Set(ByVal value As Integer)
				SetValue(TimeHoursProperty, value)
				'Me.Value = New TimeSpan(0, TimeHours, TimeMinutes, TimeSeconds, TimeTenths * 100)
			End Set
		End Property

		Public Shared ReadOnly TimeHoursProperty As DependencyProperty = _
							   DependencyProperty.Register("TimeHours", _
							   GetType(Integer), GetType(TimeSpanIncrementer), _
							   New PropertyMetadata(0))



		Public Property TimeMinutes As Integer
			Get
				Return GetValue(TimeMinutesProperty)
			End Get

			Set(ByVal value As Integer)
				If value > 59 Then
					TimeHours += (value \ 60)
					value = value Mod 60
				End If
				SetValue(TimeMinutesProperty, value)
				'Me.Value = New TimeSpan(0, TimeHours, TimeMinutes, TimeSeconds, TimeTenths * 100)
			End Set
		End Property

		Public Shared ReadOnly TimeMinutesProperty As DependencyProperty = _
							   DependencyProperty.Register("TimeMinutes", _
							   GetType(Integer), GetType(TimeSpanIncrementer), _
							   New PropertyMetadata(0))




		Public Property TimeSeconds As Integer
			Get
				Return GetValue(TimeSecondsProperty)
			End Get

			Set(ByVal value As Integer)
				If value > 59 Then
					TimeMinutes += (value \ 60)
					value = value Mod 60
				End If
				SetValue(TimeSecondsProperty, value)
				'Me.Value = New TimeSpan(0, TimeHours, TimeMinutes, TimeSeconds, TimeTenths * 100)
			End Set
		End Property

		Public Shared ReadOnly TimeSecondsProperty As DependencyProperty = _
							   DependencyProperty.Register("TimeSeconds", _
							   GetType(Integer), GetType(TimeSpanIncrementer), _
							   New PropertyMetadata(0))



		Public Property TimeTenths As Integer
			Get
				Return GetValue(TimeTenthsProperty)
			End Get

			Set(ByVal value As Integer)
				If value > 999 Then
					TimeSeconds += (value \ 1000)
					value = value Mod 1000
				End If
				SetValue(TimeTenthsProperty, value)
				'Me.Value = New TimeSpan(0, TimeHours, TimeMinutes, TimeSeconds, TimeTenths * 100)
			End Set
		End Property

		Public Shared ReadOnly TimeTenthsProperty As DependencyProperty = _
							   DependencyProperty.Register("TimeTenths", _
							   GetType(Integer), GetType(TimeSpanIncrementer), _
							   New PropertyMetadata(0))







#Region "Functions"
		''' <summary>
		''' Used by the increment button to increment the value.
		''' </summary>
		''' <param name="sender"></param>
		''' <param name="e"></param>
		''' <remarks></remarks>
		Public Sub IncrementValue(sender As Object, e As RoutedEventArgs)
			'Value += IncrementAmount
			If HoursFocused Then
				TimeHours += 1
			ElseIf MinutesFocused Then
				TimeMinutes += 1
			ElseIf SecondsFocused Then
				TimeSeconds += 1
			ElseIf TenthsFocused Then
				TimeTenths += 1
			End If
			Me.Value = New TimeSpan(0, TimeHours, TimeMinutes, TimeSeconds, TimeTenths)
		End Sub

		''' <summary>
		''' Used by the decrement button to decrement the value.
		''' </summary>
		''' <param name="sender"></param>
		''' <param name="e"></param>
		''' <remarks></remarks>
		Public Sub DecrementValue(sender As Object, e As RoutedEventArgs)
			If HoursFocused Then
				TimeHours -= 1
			ElseIf MinutesFocused Then
				TimeMinutes -= 1
			ElseIf SecondsFocused Then
				TimeSeconds -= 1
			ElseIf TenthsFocused Then
				TimeTenths -= 1
			End If
			Me.Value = New TimeSpan(0, TimeHours, TimeMinutes, TimeSeconds, TimeTenths)
		End Sub

#End Region

		''' <summary>
		''' When the control is loaded we have to disable incrementer or decrementer buttons when the value is max or min value.
		''' </summary>
		''' <param name="sender"></param>
		''' <param name="e"></param>
		''' <remarks></remarks>
		Private Sub NumericalIncrementer_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
			If Value > MaxValue Then
				Value = MaxValue
			ElseIf Value < MinValue Then
				Value = MinValue
			End If
			CheckValue()

		End Sub

		''' <summary>
		''' Checks to see if buttons should be enabled or disabled.
		''' </summary>
		''' <remarks></remarks>
		Private Sub CheckValue()
			If Value = MinValue Then
				Decrementer.IsEnabled = False
			Else
				Decrementer.IsEnabled = True
			End If
			If Value = MaxValue Then
				Incrementer.IsEnabled = False
			Else
				Incrementer.IsEnabled = True
			End If
			If Not (HoursFocused OrElse MinutesFocused OrElse SecondsFocused OrElse TenthsFocused) Then
				Incrementer.IsEnabled = False
				Decrementer.IsEnabled = False
			End If
		End Sub



		Public Property HoursFocused As Boolean
			Get
				Return GetValue(HoursFocusedProperty)
			End Get

			Set(ByVal value As Boolean)
				SetValue(HoursFocusedProperty, value)
			End Set
		End Property

		Public Shared ReadOnly HoursFocusedProperty As DependencyProperty = _
							   DependencyProperty.Register("HoursFocused", _
							   GetType(Boolean), GetType(TimeSpanIncrementer), _
							   New PropertyMetadata(False))



		Private Sub Hours_GotFocus(sender As Object, e As RoutedEventArgs) Handles Hours.GotFocus
			HoursFocused = True
			MinutesFocused = False
			SecondsFocused = False
			TenthsFocused = False
			CheckValue()
		End Sub




		Public Property MinutesFocused As Boolean
			Get
				Return GetValue(MinutesFocusedProperty)
			End Get

			Set(ByVal value As Boolean)
				SetValue(MinutesFocusedProperty, value)
			End Set
		End Property

		Public Shared ReadOnly MinutesFocusedProperty As DependencyProperty = _
							   DependencyProperty.Register("MinutesFocused", _
							   GetType(Boolean), GetType(TimeSpanIncrementer), _
							   New PropertyMetadata(False))









		Private Sub Minutes_GotFocus(sender As Object, e As RoutedEventArgs) Handles Minutes.GotFocus
			HoursFocused = False
			MinutesFocused = True
			SecondsFocused = False
			TenthsFocused = False
			CheckValue()
		End Sub

		Public Property SecondsFocused As Boolean
			Get
				Return GetValue(SecondsFocusedProperty)
			End Get

			Set(ByVal value As Boolean)
				SetValue(SecondsFocusedProperty, value)
			End Set
		End Property

		Public Shared ReadOnly SecondsFocusedProperty As DependencyProperty = _
							   DependencyProperty.Register("SecondsFocused", _
							   GetType(Boolean), GetType(TimeSpanIncrementer), _
							   New PropertyMetadata(False))


		Private Sub SecondsGotFocus(sender As Object, e As RoutedEventArgs) Handles Seconds.GotFocus
			HoursFocused = False
			MinutesFocused = False
			SecondsFocused = True
			TenthsFocused = False
			CheckValue()
		End Sub

		Public Property TenthsFocused As Boolean
			Get
				Return GetValue(TenthsFocusedProperty)
			End Get

			Set(ByVal value As Boolean)
				SetValue(TenthsFocusedProperty, value)
			End Set
		End Property

		Public Shared ReadOnly TenthsFocusedProperty As DependencyProperty = _
							   DependencyProperty.Register("TenthsFocused", _
							   GetType(Boolean), GetType(TimeSpanIncrementer), _
							   New PropertyMetadata(False))




		Private Sub TenthsGotFocus(sender As Object, e As RoutedEventArgs) Handles Tenths.GotFocus
			HoursFocused = False
			MinutesFocused = False
			SecondsFocused = False
			TenthsFocused = True
			CheckValue()
		End Sub


		Private Sub Times_PreviewKeyDown(sender As Object, e As KeyEventArgs) Handles Hours.PreviewKeyDown, Minutes.PreviewKeyDown, Seconds.PreviewKeyDown, Tenths.PreviewKeyDown
			If Not ((e.Key >= Key.D0 AndAlso e.Key <= Key.D9) OrElse (e.Key >= Key.NumPad0 AndAlso e.Key <= Key.NumPad9) OrElse (e.Key >= Key.Left AndAlso e.Key <= Key.Down) OrElse (e.Key = Key.Tab) OrElse (e.Key = Key.LeftShift OrElse e.Key = Key.RightShift)) Then
				e.Handled = True
				Return
			End If
		End Sub

		Private Sub Hours_KeyDown(sender As Object, e As KeyEventArgs) Handles Hours.KeyUp
			If Hours.Text.Length = 2 Then
				TimeHours = Hours.Text
				Value = New TimeSpan(0, TimeHours, TimeMinutes, TimeSeconds, TimeTenths)
			End If
		End Sub

		Private Sub Minutes_KeyDown(sender As Object, e As KeyEventArgs) Handles Minutes.KeyUp
			If Minutes.Text.Length = 2 Then
				TimeMinutes = Minutes.Text
				Value = New TimeSpan(0, TimeHours, TimeMinutes, TimeSeconds, TimeTenths)
			End If
		End Sub

		Private Sub Seconds_KeyDown(sender As Object, e As KeyEventArgs) Handles Seconds.KeyUp
			If Seconds.Text.Length = 2 Then
				TimeSeconds = Seconds.Text
				Value = New TimeSpan(0, TimeHours, TimeMinutes, TimeSeconds, TimeTenths)
			End If
		End Sub

		Private Sub Tenths_KeyDown(sender As Object, e As KeyEventArgs) Handles Tenths.KeyUp
			If Tenths.Text.Length = 3 Then
				TimeTenths = Tenths.Text
				Value = New TimeSpan(0, TimeHours, TimeMinutes, TimeSeconds, TimeTenths)
			End If
		End Sub


	End Class

	Public Class IsSelectedForWriting
		Inherits DependencyObject



		Public Shared Function GetIsSelectedForWriting(ByVal element As DependencyObject) As Boolean
			If element Is Nothing Then
				Throw New ArgumentNullException("element")
			End If

			Return element.GetValue(IsSelectedForWritingProperty)
		End Function

		Public Shared Sub SetIsSelectedForWriting(ByVal element As DependencyObject, ByVal value As Boolean)
			If element Is Nothing Then
				Throw New ArgumentNullException("element")
			End If

			element.SetValue(IsSelectedForWritingProperty, value)
		End Sub

		Public Shared ReadOnly IsSelectedForWritingProperty As  _
							   DependencyProperty = DependencyProperty.RegisterAttached("IsSelectedForWriting", _
							   GetType(Boolean), GetType(IsSelectedForWriting), _
							   New PropertyMetadata(False))



	End Class

End Namespace